package com.yjk.dzpoke.websocket.bean;

import cn.hutool.json.JSONUtil;
import com.yjk.dzpoke.websocket.PlayServer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class GameTurn {

    /**
     * 排序玩家
     */
    private List<String> players;

    /**
     * 玩家筹码
     */
    private Map<String, Integer> pointMap;
    /**
     * 玩家状态 0/空 正常  1全押 2退出 3离线
     */
    private Map<String, Integer> playerStatus;
    /**
     * 正在使用的牌组
     */
    private List<Poke> pokes;

    /**
     * 玩家的底牌
     */
    private Map<String, List<Poke>> pokeMap = new HashMap<>();

    /**
     * 公共牌
     */
    private List<Poke> publicPoke = new ArrayList<>();
    /**
     * 当前奖池
     */
    private Integer pool = 0;

    /**
     * 0底牌阶段 1三张 2四张 3五张
     */
    private Integer status = 0;

    /**
     * 当前操作玩家
     */
    private String currentPlayer;

    /**
     * 出价记录
     */
    private Map<String, Integer> currentBet = new HashMap<>();

    /**
     * 上一次出价
     */
    private Integer lastBet = 0;

    /**
     * 筹码基底
     */
    private Integer base = 5;

    /**
     * 输入值
     */
    private Integer inputValue;

    /**
     * 倒计时
     */
    private Integer timer = 60;

    private String smallBet;

    private String bigBet;

    public void input(Integer choice) {
        this.inputValue = choice;
        System.out.println("已选择");
    }

    public GameTurn(List<String> players, Map<String, Integer> pointMap) {
        this.players = players;
        this.pointMap = pointMap;
    }

    /**
     * 盲注
     */
    public void mz() {
        System.out.println("庄家" + players.get(0));
        if (players.size() == 2) {
            String small = players.get(1);
            smallBet = small;
            System.out.println("小盲" + small);
            currentBet.put(small, base / 2);

            String big = players.get(0);
            bigBet = big;
            System.out.println("大盲" + big);
            currentBet.put(big, base);

            currentPlayer = small;
        } else {
            String small = players.get(1);
            smallBet = small;
            System.out.println("小盲" + small);
            currentBet.put(small, base / 2);

            String big = players.get(2);
            bigBet = big;
            System.out.println("大盲" + big);
            currentBet.put(big, base);

            if (players.size() == 3) {
                currentPlayer = players.get(0);
            } else {
                currentPlayer = players.get(3);
            }
        }

        lastBet = base;

        for (String player : players) {
            List<Poke> playerPoke = Poke.getPoke(pokes, 2);
            pokeMap.put(player, playerPoke);
        }
    }

    /**
     * 当前玩家能做的选择
     *
     * @return
     */
    public Choice getPlayerChoice() {
        System.out.println("0过 1下注 2跟注 3加注 4全压 5弃牌");
        System.out.print(currentPlayer + "做选择 ");
        Integer p = pointMap.get(currentPlayer);
        if (p == 0) {
            System.out.println(currentPlayer + "已梭哈");
            return Choice.jump();
        }

        if (status == 1 && players.indexOf(currentPlayer) == 2 && lastBet == base) {
            System.out.println("可选 过 加注");
            return new Choice(currentPlayer, true, false, false, true, false);
        }

        Integer bet = currentBet.get(currentPlayer);
        if (bet != null && bet == lastBet) {
            System.out.println("本轮已结束");
            System.out.println("出价总和" + JSONUtil.parse(currentBet));
            for (Map.Entry<String, Integer> entry : pointMap.entrySet()) {
                String player = entry.getKey();
                Integer point = entry.getValue();
                Integer playBet = currentBet.get(player);
                if (playBet != null) {
                    if (playBet >= 0) {
                        pointMap.put(player, point - playBet);
                        pool += playBet;
                    } else {
                        pool += (-playBet);
                    }
                }
            }
            System.out.println("奖池" + pool);
            System.out.println("余额" + JSONUtil.parse(pointMap));
            return Choice.end();
        }

        if (lastBet == 0) {
            System.out.println("可选 过 下注");
            return new Choice(currentPlayer, true, true, false, false, false);
        } else if (lastBet == pool) {
            System.out.println("可选 跟");
            return new Choice(currentPlayer, false, false, true, false, false);
        }

        System.out.println("可选 跟 加");
        return new Choice(currentPlayer, false, false, true, true, false);

    }

    /**
     * 操作 0过 1下注 2跟注 3加注 4全压 5弃牌
     *
     * @return
     */
    public String deal() throws InterruptedException {
//        while (inputValue == null && timer > 0) {
        while (inputValue == null) {
            Thread.sleep(2000);
//            PlayServer.sendMessage(currentPlayer, JSONUtil.parse(Arrays.asList(
//                    WsMsg.timer(timer)
//            )).toString());
//            timer--;
        }
        Integer dealType;
        if (timer == 0 && inputValue == null)
            dealType = 5;
        else
            dealType = inputValue;
        boolean quit = false;
        String msg = null;
        switch (dealType) {
            case 0:
                currentBet.put(currentPlayer, lastBet);
                msg = "选择 过";
                break;
            case 1:
                lastBet = base;
                currentBet.put(currentPlayer, lastBet);
                msg = "选择 下注" + base;
                break;
            case 2:
                currentBet.put(currentPlayer, lastBet);
                msg = "选择 跟注" + lastBet;
                break;
            case 3:
                lastBet *= 2;
                if (status != 1 && lastBet > pool) lastBet = pool;
                currentBet.put(currentPlayer, lastBet);
                msg = "选择 加注" + lastBet;
                break;
            case 4:
                currentBet.put(currentPlayer, lastBet);
                msg = "选择 全押";
                break;
            case 5:
                Integer bet = currentBet.get(currentPlayer);
                if (bet == null) bet = 0;
                pointMap.put(currentPlayer, pointMap.get(currentPlayer) - bet);
                currentBet.put(currentPlayer, -bet);
                quit = true;
                msg = "选择 弃牌";
                break;
            default:
                msg = "";
        }


        inputValue = null;
        timer = 20;
        String tmp = currentPlayer;
        int i = players.indexOf(currentPlayer);
        if (i == (players.size() - 1))
            currentPlayer = players.get(0);
        else currentPlayer = players.get(i + 1);
        if (quit) players.remove(tmp);
        return msg;
    }

    public void deal(Integer v) throws InterruptedException {
        this.inputValue = v;
        deal();
    }

    /**
     * 游戏下一阶段
     *
     * @return
     */
    public boolean nextStatus() {
        System.out.println("游戏当前阶段" + status + "开始下一阶段");
        if (status > 3) return false;
        if (status == 0) {
            System.out.println("盲注下注开始");
        } else {
            if (status == 1) {
                publicPoke.addAll(Poke.getPoke(pokes, 3));
                System.out.println("发三张");
            } else if (status > 1) {
                publicPoke.addAll(Poke.getPoke(pokes, 1));
                System.out.println("发一张");
            }
            currentPlayer = players.get(0);
            lastBet = 0;
            currentBet = new HashMap<>();
        }

        status++;
        return true;
    }

    public static void main(String[] args) throws InterruptedException {


        List<String> players = new ArrayList<>();
        players.add("yjk");
        players.add("yxh");
        players.add("gln");
        players.add("zjs");

        Map map = new HashMap();
        for (String player : players) {
            map.put(player, 500);
        }

        System.out.println("玩家排序" + players);
        GameTurn gameTurn = new GameTurn(players, map);
        gameTurn.setPokes(Poke.NewPokes());
        gameTurn.mz();

        for (Map.Entry<String, List<Poke>> entry : gameTurn.pokeMap.entrySet()) {
            System.out.println(entry.getKey() + entry.getValue());
        }

        while (gameTurn.nextStatus()) {
            if (gameTurn.status > 1) {

            }
            Choice choice = gameTurn.getPlayerChoice();
            while (!choice.getEnd()) {
                Scanner scanner = new Scanner(System.in);
                if (scanner.hasNext()) {
                    String str1 = scanner.next();
                    gameTurn.deal(Integer.parseInt(str1));
                }
                choice = gameTurn.getPlayerChoice();
            }
            System.out.println("公共牌" + gameTurn.publicPoke);
        }
        System.out.println("公共牌" + gameTurn.publicPoke);

        String winner = null;
        PokeType pokeType = null;
        for (String player : players) {
            List<Poke> hand = gameTurn.pokeMap.get(player);
            PokeType type = PokeType.getType(hand, gameTurn.publicPoke);
            System.out.println(player + "底牌" + hand + " 牌型" + type);
            if (winner == null) {
                winner = player;
                pokeType = type;
            } else {
                if (pokeType.compareTo(type) < 0) {
                    winner = player;
                    pokeType = type;
                }
            }
        }
        System.out.println("赢家是" + winner + "牌型是" + pokeType);
    }
}
